package com.ruoyi.web.controller.system;

import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.domain.entity.Type;
import com.ruoyi.system.service.ITypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.Doc;
import com.ruoyi.system.service.IDocService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 文档Controller
 * 
 * @author tq
 * @date 2025-04-19
 */
@RestController
@RequestMapping("/system/doc")
public class DocController extends BaseController
{
    @Autowired
    private IDocService docService;
    @Autowired
    private ITypeService typeService;

    private static final Logger LOGGER = LoggerFactory.getLogger(DocController.class);

    /**
     * 查询文档列表
     */
    @PreAuthorize("@ss.hasPermi('system:doc:list')")
    @GetMapping("/list")
    public TableDataInfo list(Doc doc)
    {
        startPage();
        List<Doc> list = docService.selectDocList(doc);
        return getDataTable(list);
    }

    /**
     * 导出文档列表
     */
    @PreAuthorize("@ss.hasPermi('system:doc:export')")
    @Log(title = "文档", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Doc doc)
    {
        List<Doc> list = docService.selectDocList(doc);
        ExcelUtil<Doc> util = new ExcelUtil<Doc>(Doc.class);
        util.exportExcel(response, list, "文档数据");
    }

    /**
     * 获取文档详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:doc:query')")
    @GetMapping(value = "/{docId}")
    public AjaxResult getInfo(@PathVariable("docId") Long docId)
    {
        return success(docService.selectDocByDocId(docId));
    }

    /**
     * 新增文档
     */
    @PreAuthorize("@ss.hasPermi('system:doc:add')")
    @Log(title = "文档", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Doc doc)
    {
        return toAjax(docService.insertDoc(doc));
    }

    /**
     * 修改文档
     */
    @PreAuthorize("@ss.hasPermi('system:doc:edit')")
    @Log(title = "文档", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Doc doc)
    {
        return toAjax(docService.updateDoc(doc));
    }

    /**
     * 删除文档
     */
    @PreAuthorize("@ss.hasPermi('system:doc:remove')")
    @Log(title = "文档", businessType = BusinessType.DELETE)
	@DeleteMapping("/{docIds}")
    public AjaxResult remove(@PathVariable Long[] docIds)
    {
        return toAjax(docService.deleteDocByDocIds(docIds));
    }

    /**
     * 获取部门树列表
     */
    @PreAuthorize("@ss.hasPermi('system:doc:list')")
    @GetMapping("/typeTree")
    public AjaxResult typeTree(Type type)
    {
        return success(typeService.selectTreeList(type));
    }

    /**
     * 批量上传PDF文档
     */
    @PreAuthorize("@ss.hasPermi('system:doc:add')")
    @Log(title = "批量上传文档", businessType = BusinessType.INSERT)
    @PostMapping("/batchUpload")
    public AjaxResult batchUpload(
            @RequestParam("files") MultipartFile[] files,
            @RequestParam("typeId") Long typeId,
            @RequestParam(value = "unitId", required = false) Long unitId,
            @RequestParam(value = "loc", required = false) String loc)
    {
        try {
            // 检查文件数量，如果超过18个文件，建议使用分块上传
            if (files.length > 18) {
                LOGGER.warn("上传文件数量过多: {}, 建议使用分块上传接口", files.length);
                return AjaxResult.warn("文件数量过多(" + files.length + "个)，建议分批上传，每批不超过18个文件");
            }
            
            int result = docService.batchUploadDocs(files, typeId, unitId, loc);
            return AjaxResult.success("成功上传 " + result + " 个文件");
        } catch (Exception e) {
            LOGGER.error("批量上传文档失败", e);
            return AjaxResult.error("上传失败: " + e.getMessage());
        }
    }

    /**
     * 分块批量上传PDF文档
     */
    @PreAuthorize("@ss.hasPermi('system:doc:add')")
    @Log(title = "分块批量上传文档", businessType = BusinessType.INSERT)
    @PostMapping("/chunkBatchUpload")
    public AjaxResult chunkBatchUpload(
            @RequestParam("files") MultipartFile[] files,
            @RequestParam("typeId") Long typeId,
            @RequestParam(value = "unitId", required = false) Long unitId,
            @RequestParam(value = "loc", required = false) String loc,
            @RequestParam(value = "chunkIndex", defaultValue = "0") int chunkIndex,
            @RequestParam(value = "totalChunks", defaultValue = "1") int totalChunks,
            @RequestParam(value = "totalFiles", required = false) Integer totalFiles)
    {
        try {
            // 平衡配置：提高效率但保持稳定
            int maxFilesPerChunk = 20; // 默认限制
            
            if (totalFiles != null) {
                if (totalFiles > 1000) {
                    maxFilesPerChunk = 18; // 大量文件，每批18个
                } else if (totalFiles > 500) {
                    maxFilesPerChunk = 20; // 中等数量，每批20个
                } else {
                    maxFilesPerChunk = 20; // 少量文件，每批20个
                }
            }
            
            if (files.length > maxFilesPerChunk) {
                return AjaxResult.error("单批次文件数量不能超过" + maxFilesPerChunk + "个，当前: " + files.length + 
                    (totalFiles != null ? "（总文件数：" + totalFiles + "）" : ""));
            }
            
            // 计算批次文件总大小
            long totalSize = 0;
            for (MultipartFile file : files) {
                totalSize += file.getSize();
            }
            double totalSizeMB = totalSize / 1024.0 / 1024.0;
            
            LOGGER.info("处理分块上传: 第{}/{}批, 文件数量: {}, 总大小: {}MB", 
                    chunkIndex + 1, totalChunks, files.length, String.format("%.2f", totalSizeMB));
            
            int result = docService.batchUploadDocs(files, typeId, unitId, loc);
            
            String message = String.format("第%d/%d批上传完成，本批成功上传 %d 个文件", 
                    chunkIndex + 1, totalChunks, result);
            
            return AjaxResult.success(message).put("chunkIndex", chunkIndex)
                    .put("totalChunks", totalChunks)
                    .put("uploadedCount", result)
                    .put("isLastChunk", chunkIndex == totalChunks - 1);
                    
        } catch (Exception e) {
            LOGGER.error("分块批量上传文档失败: 第{}/{}批", chunkIndex + 1, totalChunks, e);
            return AjaxResult.error(String.format("第%d/%d批上传失败: %s", 
                    chunkIndex + 1, totalChunks, e.getMessage()));
        }
    }
}
